//
//  DESCrypts.m
//  Lrjh
//
//  Created by 李同学 on 2025/7/21.
//

#import "DESCrypts.h"
#import <CommonCrypto/CommonCrypto.h>

@implementation DESCrypts

static NSString *_encode = @"UTF-8";
+ (NSString *)EncrKey {
    return @"MywayLZW";
}

+ (NSString *)encode {
    return _encode;
}

+ (void)setEncode:(NSString *)encode {
    _encode = encode;
}

+ (NSString *)Encrypt:(NSString *)pToEncrypt {
    return [self Encrypt:pToEncrypt withKey:self.EncrKey];
}

+ (NSString *)Decrypt:(NSString *)pToDecrypt {
    return [self Decrypt:pToDecrypt withKey:self.EncrKey];
}

+ (NSString *)Encrypt:(NSString *)message withKey:(NSString *)key {
    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t dataOutAvailable = messageData.length + kCCBlockSizeDES;
    void *dataOut = malloc(dataOutAvailable);
    size_t dataOutMoved = 0;
    
    CCCryptorStatus result = CCCrypt(kCCEncrypt,
                                     kCCAlgorithmDES,
                                     kCCOptionPKCS7Padding,
                                     keyData.bytes,
                                     kCCKeySizeDES,
                                     keyData.bytes, // IV same as key
                                     messageData.bytes,
                                     messageData.length,
                                     dataOut,
                                     dataOutAvailable,
                                     &dataOutMoved);
    if (result == kCCSuccess) {
        NSData *encryptedData = [NSData dataWithBytesNoCopy:dataOut length:dataOutMoved];
        return [self toHexString:encryptedData];
    } else {
        free(dataOut);
        return nil;
    }
}

+ (NSString *)Decrypt:(NSString *)message withKey:(NSString *)key {
    NSData *cipherData = [self convertHexString:message];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t dataOutAvailable = cipherData.length + kCCBlockSizeDES;
    void *dataOut = malloc(dataOutAvailable);
    size_t dataOutMoved = 0;
    
    CCCryptorStatus result = CCCrypt(kCCDecrypt,
                                     kCCAlgorithmDES,
                                     kCCOptionPKCS7Padding,
                                     keyData.bytes,
                                     kCCKeySizeDES,
                                     keyData.bytes, // IV same as key
                                     cipherData.bytes,
                                     cipherData.length,
                                     dataOut,
                                     dataOutAvailable,
                                     &dataOutMoved);
    if (result == kCCSuccess) {
        NSData *decryptedData = [NSData dataWithBytesNoCopy:dataOut length:dataOutMoved];
        NSString *plainText = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
        return plainText;
    } else {
        free(dataOut);
        return nil;
    }
}

+ (NSData *)convertHexString:(NSString *)hexString {
    NSMutableData *data = [[NSMutableData alloc] init];
    int idx = 0;
    while (idx + 2 <= hexString.length) {
        NSString *byteString = [hexString substringWithRange:NSMakeRange(idx, 2)];
        NSScanner *scanner = [NSScanner scannerWithString:byteString];
        unsigned int byteValue;
        [scanner scanHexInt:&byteValue];
        uint8_t b = byteValue;
        [data appendBytes:&b length:1];
        idx += 2;
    }
    return data;
}

+ (NSString *)toHexString:(NSData *)data {
    const unsigned char *dataBuffer = (const unsigned char *)data.bytes;
    if (!dataBuffer) return [NSString string];
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(data.length * 2)];
    for (int i = 0; i < data.length; ++i) {
        [hexString appendFormat:@"%02x", dataBuffer[i]];
    }
    return [hexString copy];
}

@end

